package com.cs.beneficios.common.util;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

import com.cs.beneficios.business.model.BeneficiarioVO;

public class Utility {


	// ------------------------------------------------------------------------
	// Constantes
	// ------------------------------------------------------------------------

	/**
	 * Formato estandar para la fecha
	 */
	public static final String DATE_FORMAT = "DD/MM/YYYY";

	// ------------------------------------------------------------------------
	// Metodo Publicos
	// ------------------------------------------------------------------------

	/**
	 * Retorna una fecha tipo <code>java.util.Date</code> a partir de una cadena
	 * de caracteres en el formato indicado en la constante DATE_FORMAT.
	 * 
	 * @param dateAsString
	 *            Cadena de caracteres que indica una fecha en el formato
	 *            indicado en la constante DATE_FORMAT.
	 * 
	 * @return Fecha calculada a partir de la cadena indicada.
	 */
	public static Date getDateFromString(String dateAsString)
		throws Exception {
		// Variables locales
		Date date = null;
		SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT);
		// Hace setLenient para que la conversion sea mas flexible en cuanto al
		// formato.
		sdf.setLenient(false);
		try {
			date = sdf.parse(dateAsString);
		} catch (ParseException e) {
			throw new Exception("Formato de fecha no valido. " + dateAsString);
		}
		return date;
	}

	/**
	 * Retorna una fecha tipo <code>java.util.Date</code> a partir de una fecha
	 * del mismo tipo de clase, en el formato indicado en la constante
	 * DATE_FORMAT.
	 * 
	 * @param dateAsString
	 *            Cadena de caracteres que indica una fecha en el formato
	 *            indicado en la constante DATE_FORMAT.
	 * 
	 * @return Fecha calculada a partir de la cadena indicada.
	 */
	public static Date getFormatedDate(java.util.Date uDate) throws Exception {
		// Variables locales
		Date date = null;
		SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT);
		// Hace setLenient para que la conversion sea mas flexible en cuanto al
		// formato.
		sdf.setLenient(false);
		// Conversion de la fecha
		try {
			date = sdf.parse(sdf.format(uDate));
		} catch (ParseException e) {
			throw new Exception("Formato de fecha no valido. " + uDate);
		}
		return date;
	}

	/**
	 * Retorna una cadena de caracteres que representa la fecha indicada con el
	 * formato indicado en la constante DATE_FORMAT.
	 * 
	 * @param date
	 *            Fecha a convertir en cadena de caracteres.
	 * 
	 * @return Cadena de caracteres que representa la fecha en el formato.
	 */
	public static String getStringFromDate(Date date) throws Exception {
		SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT);
		String aux = null;
		sdf.setLenient(false);
		try {
			if (date != null) {
				aux = sdf.format(date);
			}
		} catch (Exception e) {
			throw new Exception("Formato de fecha no valido.");
		}
		sdf = null;
		return aux;
	}

	/**
	 * Convierte un objeto de tipo java.util.Date a su correspondiente en
	 * java.sql.Date.
	 * 
	 * @param date
	 *            Objeto java.util.Date
	 * 
	 * @return Objeto java.sql.Date
	 */
	public static java.sql.Date getSQLDate(Date date) {
		java.sql.Date sqlDate = null;
		SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT);
		sdf.setLenient(false);
		if (date != null) {
			sqlDate = java.sql.Date.valueOf(sdf.format(date));
		}
		return sqlDate;
	}

	/**
	 * Convierte un objeto de tipo java.sql.Date a su correspondiente en
	 * java.util.Date.
	 * 
	 * @param date
	 *            Objeto java.sql.Date
	 * 
	 * @return Objeto java.util.Date
	 */
	public static java.util.Date sqlDateToUtilDate(java.sql.Date fecha)
		throws ParseException {
		SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT);
		sdf.setLenient(false);
		return sdf.parse(sdf.format(fecha));
	}

	/**
	 * Obtiene el siguiente valor de una secuencia determinada.
	 * 
	 * @param sequenceName
	 *            Nombre de la secuencia.
	 * @param conn
	 *            Este metodo requiere una conexion a la base de datos
	 * 
	 * @return Siguiente valor de la secuencia.
	 * @throws SQLException
	 */
	public static long getSequenceNextValue(
		Connection conn,
		String sequenceName)
		throws SQLException {
		// Variables locales
		long value = 0;
		Statement statement = null;
		ResultSet resultSet = null;
		StringBuffer query = new StringBuffer(256);
		query.append("SELECT ");
		query.append(sequenceName.trim());
		query.append(".NEXTVAL codigo FROM dual");
		try {
			statement = conn.createStatement();
			resultSet = statement.executeQuery(query.toString());
			if (resultSet.next()) {
				value = resultSet.getLong("codigo");
			}
		} catch (Exception ex) {
			ex.printStackTrace();
			throw new SQLException(
				"IISAM [SQLEXCEPTION]: Error obteniendo un nuevo valor de secuencia "
					+ sequenceName);
		} finally {
			if (resultSet != null) {
				resultSet.close();
			}
			if (statement != null) {
				statement.close();
			}
		}
		query = null;
		statement = null;
		resultSet = null;
		return value;
	}

	/**
	 * Formatea todos los campos que traen una convencion numerica del SISBEN a
	 * una convencion alfanumerica del SUB.
	 * 
	 * @param beneficiary
	 */
	public static void formatSisben(BeneficiarioVO beneficiary) {
		formatSisbenDocument(beneficiary);
		formatSisbenSex(beneficiary);
//		formatSisbenParentesco(beneficiary);
	}

	/**
	 * Cambia el formato del tipo de documento, de numerico que es alamacenado
	 * en el SISBEN a alfanumerico el cual es el estandar del sistema SUB.
	 * 
	 * @param beneficiary
	 */
	public static void formatSisbenDocument(BeneficiarioVO beneficiary) {
		switch (Integer.parseInt(beneficiary.getTipoDocumento())) {
			case 1 :
				beneficiary.setTipoDocumento("C");
				break;
			case 2 :
				beneficiary.setTipoDocumento("T");
				break;
			case 3 :
				beneficiary.setTipoDocumento("E");
				break;
			case 4 :
				beneficiary.setTipoDocumento("R");
				break;
			case 0 :
				beneficiary.setTipoDocumento("O");
				break;
			default :
				break;
		}
	}

	/**
	 * Cambia el formato del parentesco, de numerico que es alamacenado en el
	 * SISBEN a alfanumerico el cual es el estandar del sistema SUB.
	 * 
	 * @param beneficiary
	 */
	public static void formatSisbenParentesco(BeneficiarioVO beneficiary) {
		switch (Integer.parseInt(beneficiary.getParentesco())) {
			case 1 :
				beneficiary.setParentesco("Jefe");
				break;
			case 2 :
				beneficiary.setParentesco("conyugue o companero(a)");
				break;
			case 3 :
				beneficiary.setParentesco("hijo(a) / hijastro(a)");
				break;
			case 4 :
				beneficiary.setParentesco("Nieto(a)");
				break;
			case 5 :
				beneficiary.setParentesco("Padre / Madre");
				break;
			case 6 :
				beneficiary.setParentesco("Hermano(a)");
				break;
			case 7 :
				beneficiary.setParentesco("Yerno / Nuera");
				break;
			case 8 :
				beneficiary.setParentesco("Abuelo(a)");
				break;
			case 9 :
				beneficiary.setParentesco("Suegro(a)");
				break;
			case 10 :
				beneficiary.setParentesco("Tio(a)");
				break;
			case 11 :
				beneficiary.setParentesco("Sobrino(a)");
				break;
			case 12 :
				beneficiary.setParentesco("Primo(a)");
				break;
			case 13 :
				beneficiary.setParentesco("Cunado(a)");
				break;
			case 14 :
				beneficiary.setParentesco("Otros parientes");
				break;
			case 15 :
				beneficiary.setParentesco("Otros no parientes");
				break;
			case 16 :
				beneficiary.setParentesco("Servicio domestico o cuidandero");
				break;
			case 17 :
				beneficiary.setParentesco(
					"Pariente de servicio domestico o cuidandero");
				break;
			default :
				break;
		}
	}

	/**
	 * Cambia el formato del sexo, de numerico que es alamacenado en el SISBEN a
	 * alfanumerico el cual es el estandar del sistema SUB.
	 * 
	 * @param beneficiary
	 */
	public static void formatSisbenSex(BeneficiarioVO beneficiary) {
		switch (Integer.parseInt(beneficiary.getSexo())) {
			case 1 :
				beneficiary.setSexo("M");
				break;
			case 2 :
				beneficiary.setSexo("F");
				break;
			default :
				break;
		}
	}

	/**
	 * Cambia el formato del documento en el estandar de planeacion C/E/R/T hacia el formato del SISBEN 1/2/3/4
	 * @param documentType tipo de documento a formatear.
	 */
	public static String deformatSisbenDocument(String documentType) {
		if ("C".equals(documentType)) {
			documentType = "1";
		} else if ("R".equals(documentType)) {
			documentType = "4";
		} else if ("T".equals(documentType)) {
			documentType = "2";
		} else if ("E".equals(documentType)) {
			documentType = "3";
		}
		return documentType;
	} // fin deformat sisben
	
	/**
	 * Cambia el formato del documento en el estandar de planeacion C/E/R/T hacia el formato del SISBEN 1/2/3/4
	 * @param documentType tipo de documento a formatear.
	 */
	public static String deformatSisbenDocumentToSubDocument(String documentType) {
		if ("1".equals(documentType)) {
			documentType = "C";
		} else if ("4".equals(documentType)) {
			documentType = "R";
		} else if ("2".equals(documentType)) {
			documentType = "T";
		} else if ("3".equals(documentType)) {
			documentType = "E";
		}
		return documentType;
	} // fin deformat sisben

	/**
	 * Cambia el formato del documento en el estandar de planeacion C/E/R/T hacia el formato del SIPOD CC/RC/TI/CE
	 * @param documentType tipo de documento a formatear.
	 */
	public static String deformatSipodDocument(String documentType) {
		if ("C".equals(documentType)) {
			documentType = "CC";
		} else if ("R".equals(documentType)) {
			documentType = "RC";
		} else if ("T".equals(documentType)) {
			documentType = "TI";
		} else if ("E".equals(documentType)) {
			documentType = "CE";
		}
		return documentType;
	} // fin deformat sisben

	/**
	 * Cambia el formato del documento en el estandar de del SISBENv2 CC/RC/TI/CE hacia el formato del SISBENv3 1/2/3/4
	 * @param documentType tipo de documento a formatear.
	 */
	public static String deformatSisben2ToSisben3Document(String documentType) {
		if ("CC".equals(documentType)) {
			documentType = "1";
		} else if ("RC".equals(documentType)) {
			documentType = "4";
		} else if ("TI".equals(documentType)) {
			documentType = "2";
		} else if ("CE".equals(documentType)) {
			documentType = "3";
		}
		return documentType;
	} // fin deformat sisben

	/**
	 * Cambia el formato del tipo de documento, de numerico que es alamacenado
	 * en el SISBEN3 a alfanumerico el cual es el estandar del sistema SISBEN2.
	 * 
	 * @param beneficiary
	 */
	public static String deformatSisbenDosDocument(String documentType) {
		if ("1".equals(documentType)) {
			documentType = "CC";
		} else if ("4".equals(documentType)) {
			documentType = "RC";
		} else if ("2".equals(documentType)) {
			documentType = "TI";
		} else if ("3".equals(documentType)) {
			documentType = "CE";
		}
		return documentType;
	}

	
}
